package com.swak.persistence;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import com.swak.utils.StringUtils;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * 选择性: 查询、清空列
 * 
 * @author lifeng
 */
@Getter
@Setter
@Accessors(chain = true)
public class Selective extends QueryCondition implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * 需要检索的列
	 */
	protected List<Object> columns;

	/**
	 * 校验Selective的有效性
	 * 
	 * @return
	 */
	public boolean isSelectiveValid() {
		return columns != null && columns.size() > 0 && super.isValid();
	}

	public Selective select(Object column) {
		if (column == null) {
			throw new RuntimeException("column cannot be null");
		}
		if (columns == null) {
			columns = new ArrayList<Object>();
		}
		columns.add(QueryCondition.escape(column));
		return this;
	}

	public Selective select(Object... columns) {
		if (columns == null || columns.length == 0) {
			throw new RuntimeException("columns cannot be null");
		}
		for (Object column : columns) {
			this.select(column);
		}
		return this;
	}

	public Selective andIsNull(String column) {
		if (StringUtils.isNotBlank(column)) {
			getCriteria().andIsNull(column);
		}
		return this;
	}

	public Selective andIsNotNull(String column) {
		if (StringUtils.isNotBlank(column)) {
			getCriteria().andIsNotNull(column);
		}
		return this;
	}

	public Selective andConditionSql(String conditionSql) {
		if (StringUtils.isNotBlank(conditionSql)) {
			getCriteria().andConditionSql(conditionSql);
		}
		return this;
	}

	public Selective andEqualTo(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andEqualTo(column, value);
		}
		return this;
	}

	public Selective andNotEqualTo(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andNotEqualTo(column, value);
		}
		return this;
	}

	public Selective andGreaterThan(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andGreaterThan(column, value);
		}
		return this;
	}

	public Selective andGreaterThanOrEqualTo(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andGreaterThanOrEqualTo(column, value);
		}
		return this;
	}

	public Selective andLessThan(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andLessThan(column, value);
		}
		return this;
	}

	public Selective andLessThanOrEqualTo(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andLessThanOrEqualTo(column, value);
		}
		return this;
	}

	public Selective andIn(String column, List<?> values) {
		if (StringUtils.isNotBlank(column) && values != null) {
			this.getCriteria().andIn(column, values);
		}
		return this;
	}

	public Selective andNotIn(String column, List<?> values) {
		if (StringUtils.isNotBlank(column) && values != null) {
			this.getCriteria().andNotIn(column, values);
		}
		return this;
	}

	public Selective andBetween(String column, Object value1, Object value2) {
		if (StringUtils.isNotBlank(column) && value1 != null && value2 != null) {
			this.getCriteria().andBetween(column, value1, value2);
		}
		return this;
	}

	public Selective andNotBetween(String column, Object value1, Object value2) {
		if (StringUtils.isNotBlank(column) && value1 != null && value2 != null) {
			this.getCriteria().andBetween(column, value1, value2);
		}
		return this;
	}

	public Selective andLike(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andLike(column, value);
		}
		return this;
	}

	public Selective andLeftLike(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andLeftLike(column, value);
		}
		return this;
	}

	public Selective andRightLike(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andRightLike(column, value);
		}
		return this;
	}

	public Selective andNotLike(String column, Object value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andNotLike(column, value);
		}
		return this;
	}

	public Selective andDateEqualTo(String column, LocalDateTime value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andDateEqualTo(column, value);
		}
		return this;
	}

	public Selective andDateNotEqualTo(String column, LocalDateTime value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andDateNotEqualTo(column, value);
		}
		return this;
	}

	public Selective andDateGreaterThan(String column, LocalDateTime value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andDateGreaterThan(column, value);
		}
		return this;
	}

	public Selective andDateGreaterThanOrEqualTo(String column, LocalDateTime value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andDateGreaterThanOrEqualTo(column, value);
		}
		return this;
	}

	public Selective andDateLessThan(String column, LocalDateTime value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andDateLessThan(column, value);
		}
		return this;
	}

	public Selective andDateLessThanOrEqualTo(String column, LocalDateTime value) {
		if (StringUtils.isNotBlank(column) && value != null) {
			this.getCriteria().andDateLessThanOrEqualTo(column, value);
		}
		return this;
	}

	public Selective andDateIn(String column, List<LocalDateTime> values) {
		if (StringUtils.isNotBlank(column) && values != null) {
			this.getCriteria().andDateIn(column, values);
		}
		return this;
	}

	public Selective andDateNotIn(String column, List<LocalDateTime> values) {
		if (StringUtils.isNotBlank(column) && values != null) {
			this.getCriteria().andDateNotIn(column, values);
		}
		return this;
	}

	public Selective andDateBetween(String column, LocalDateTime value1, LocalDateTime value2) {
		if (StringUtils.isNotBlank(column) && value1 != null && value2 != null) {
			this.getCriteria().andDateBetween(column, value1, value2);
		}
		return this;
	}

	public Selective andDateNotBetween(String column, LocalDateTime value1, LocalDateTime value2) {
		if (StringUtils.isNotBlank(column) && value1 != null && value2 != null) {
			this.getCriteria().andDateNotBetween(column, value1, value2);
		}
		return this;
	}

	public Selective orderBy(String orderBy) {
		if (StringUtils.isNotBlank(orderBy)) {
			this.setOrderByClause(orderBy);
		}
		return this;
	}

	public Selective ascOrderBy(String column) {
		if (StringUtils.isNotBlank(column)) {
			this.setOrderByClause(column + " ASC");
		}
		return this;
	}

	public Selective descOrderBy(String column) {
		if (StringUtils.isNotBlank(column)) {
			this.setOrderByClause(column + " DESC");
		}
		return this;
	}

	public static Selective of() {
		return new Selective();
	}

}